<?php

namespace app\service;

use app\exception\ModelEmptyException;
use app\exception\ModelException;
use app\model\Admin;
use app\model\Attachment;
use app\model\Category;
use app\model\CategoryCheck;
use app\model\CategorySubContent;
use app\model\InnerChart;
use app\model\InnerChartSubContent;
use app\model\Model;
use app\model\Module;
use app\model\ModuleField;
use app\model\RecycleBin;
use app\model\SubContent;
use app\model\SubContentCheck;
use app\model\SubContentCheckStep;
use app\model\SubContentHistory;
use app\model\Tag;
use app\model\Website;
use app\scaffold\Table;
use Overtrue\Pinyin\Pinyin;
use think\Exception;
use think\exception\ValidateException;
use think\facade\Cache;
use think\facade\Db;

class ContentService {

    /**
     * @var \app\model\Content
     */
    public static $model = null;
    /**
     * @var array
     */
    public static $macro = [];

    public static $hasOne = [];

    public static $belongsTo = [];

    public static $hasMany = [];

    protected static $arrayField =  ['多图','多视频','多文件','日期时间区间','列表多选','多选'];

    /**
     * @var \app\scaffold\Table
     */
    protected $table;

    public function __construct()
    {
        $this->table = new Table();
    }

    /**
     * @throws ModelException
     * @throws ModelEmptyException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\db\exception\DbException
     */
    public static function tagTagContentList()
    {
        if(empty($param['limit'])){
            $param['limit'] = null;
        }
        $tids = explode(',',$param['cid']);
        if(!count($tids)){
            return [];
        }

        $module = self::getModule($param['module_id'],$param['sellerId']);
        $table = $module['table'];
        $attachField = self::getAttachField($module['moduleField']);
        self::setModel($table);
        $cateSub = new CategorySubContent();
        if(count($tids) == 1){
            $where = [
                'tag_id' => $tids[0],
                'seller_id' => $param['sellerId'],
                'website_id' => $param['websiteId']
            ];
        }else{
            $where = [
                ['category_id','in',$tids],
                ['seller_id','=',$param['sellerId']],
                ['website_id','=', $param['websiteId']]
            ];
        }
        $cateSubCon = $cateSub->getAllCustomArrayData($where)['data'];
        return self::tagContent($cateSubCon, $param, $attachField);
    }

    /**
     * @throws ModelEmptyException
     * @throws \think\db\exception\DataNotFoundException
     * @throws ModelException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\db\exception\DbException
     */
    public static function getTagRecommend($param)
    {
        $cid = (int)input('cid');
        if(empty($param['cid'])){
            if($cid){
                $cateIds = [$cid];
            }else{
                return [];
            }
        }else{
            $cateIds = explode(',',$param['cid']);
        }
        $Category = new Category();
        if(count($cateIds) == 1){
            $cate = $Category->getCategory(['id'=>$cateIds[0],'seller_id'=>$param['sellerId'],'website_id'=>$param['siteId'],'lang'=>$param['lang']])['data']->toArray();
            $parentPath = $cate['path'] . $cate['id'] . '-';
            $cates = $Category->getCategoryList([['path','like',$parentPath . '%'],['seller_id','=',$param['sellerId']],['website_id','=' ,$param['siteId']],['lang','=',$param['lang']]])['data']->toArray();
            $cates[] = $cate;
            $cateIds= array_column($cates,'id');
        }else{
            $cates = $Category->getCategoryList([['id','in',$cateIds],['website_id','=' ,$param['siteId']]])['data']->toArray();
            $cateIdArr= array_column($cates,'id');
            $cateIds = array_intersect($cateIds,$cateIdArr);
        }
        $module = self::getModule($param['module_id'],$param['sellerId']);
        $table = $module['table'];
        $attachField = self::getAttachField($module['moduleField']);
        self::setModel($table);
        $cateSub = new CategorySubContent();
        $subId = (int)input('id');
        $where = [
            ['csc.category_id','in',$cateIds],
            ['csc.seller_id','=',$param['sellerId']],
            ['sc.is_del','=','1']
        ];
        if($subId && $cid){
            $where[] = ['sub_content_id','<>',$subId];
        }
        $cateSubCon = $cateSub
            ->alias('csc')
            ->leftJoin('sub_content sc','sc.id = csc.sub_content_id')
            ->where($where)->select()->toArray();
        if(!empty($cateSubCon)){
            $cateSubConLen =  count($cateSubCon);
            if( $cateSubConLen < $param['limit']){
                $param['limit'] = $cateSubConLen;
            }
            $cateSubConKey = array_rand($cateSubCon,$param['limit']);
            if(!is_array($cateSubConKey)){
                $cateSubConKey = [$cateSubConKey];
            }
            $tmp = [];
            if(!empty($cateSubConKey)){
                foreach ($cateSubConKey as $val){
                    $tmp[] = $cateSubCon[$val];
                }
                $cateSubCon = $tmp;
            }
        }
        return self::tagContent($cateSubCon, $param, $attachField);
    }

    /**
     * @throws ModelException
     * @throws ModelEmptyException
     */
    public static function getTagContentDetail($id, $sellerId, $lang, $siteId)
    {
        try {
            $SubContent = new SubContent();
            $where = [
                ['id','=',$id],
                ['seller_id','=',$sellerId],
                ['publish_time','<',date('Y-m-d H:i:s',time())],
                ['status','=',1],
                ['is_del','=',1],
            ];
            $subContent = $SubContent->getSubContent($where,['thumbnail'=>function($q){
                $q->field('id,name,url,type,description');
            },'cover'=>function($q){
                $q->field('id,name,url,type,description');
            }])['data']->toArray();

            $cate = (new Category())->alias('a')
                ->with('module.moduleField')
                ->join('category_sub_content b', 'a.id = b.category_id')
                ->where('b.sub_content_id', $id)
                ->where('a.seller_id', $sellerId)
                ->where('a.website_id', $siteId)
                ->where('a.lang', $lang)
                ->select()->toArray();
            $subContent['category'] = $cate;

            $article = '';
            if(!empty($cate)){
                $table = $cate['0']['module']['table'];
                self::setModel($table);
                $article = self::$model->where(['sub_id' => $id, 'seller_id' => $sellerId])->find();
                $attachField = self::setSpecialField($cate[0]['module']['moduleField']);
                self::getSpecialField($article,$attachField);
            }
            $subContent['main_content'] = $article;
        }catch (ModelEmptyException $me){
            throw new ModelEmptyException($me->getMessage());
        } catch (\Exception $e){
            throw new ModelException($e->getMessage());
        }
        return $subContent;
    }

    /**
     * 分页标签数据
     * @throws ModelException
     */
    public static function tagContentPage($param)
    {
        if(!empty($param['cid'])){
            $cid = $param['cid'];
        }else{
            $cid = (int)request()->param('id');
        }
        $Category = new Category();
        $cate = $Category->getCategory(['id'=>$cid,'seller_id'=>$param['sellerId'],'lang'=>$param['lang']],['module.moduleField'])['data']->toArray();
        if($cate['parent_map'] && empty($param['cid'])){
            $cate = $Category->getCategory(['id'=>$cate['parent_map'],'seller_id'=>$param['sellerId'],'lang'=>$param['lang']],['module.moduleField'])['data']->toArray();
        }
        $path = $cate['path'] . $cid . '-';
        $cates = $Category->getCategoryList([['website_id','=',$param['siteId']],['lang','=',$param['lang']],['path','like',$path.'%']])['data']->toArray();
        if(empty($param['limit'])){
            $param['limit'] = null;
        }
        $cateIds = array_column($cates,'id');
        array_push($cateIds,$cid);
        if(!count($cateIds)){
            return [];
        }
        $table = $cate['module']['table'];
        self::setModel($table);
        $attachField = self::getAttachField($cate['module']['moduleField']);
        $cateSub = new CategorySubContent();
        if(count($cateIds) == 1){
            $where = [
                'category_id' => $cateIds[0],
                'seller_id' => $param['sellerId'],
            ];
        }else{
            $where = [
                ['category_id','in',$cateIds],
                ['seller_id','=',$param['sellerId']],
            ];
        }

        $cateSubCon = $cateSub->where($where)->select()->toArray();
        return self::tagContent($cateSubCon, $param, $attachField);
    }

    /**
     * 内容标签数据
     * @throws ModelEmptyException
     * @throws ModelException
     */
    public static function tagContentList($param)
    {
        $module = self::getModule($param['module_id'],$param['sellerId']);
        $table = $module['table'];
        self::setModel($table);
        if(empty($param['limit'])){
            $param['limit'] = null;
        }
        $cateIds = explode(',',$param['cid']);
        if(!count($cateIds)){
            return [];
        }
        $Category = new Category();

        if($param['all'] == 1){
            $cid = $cateIds[0];
            $cate = $Category->getCustomArrayData([['id','=',$cid],['website_id','=' ,$param['siteId']]])['data'];
            $path = $cate['path'] . $cid . '-';
            $subCate = $Category->getAllCustomArrayData([['path','like',$path . '%'],['website_id','=' ,$param['siteId']]])['data'];
            $cateIds = array_column($subCate,'id');
            $cateIds[] = $cid;
        }else{
            $cates = $Category->getAllCustomArrayData([['id','in',$cateIds],['website_id','=' ,$param['siteId']]])['data'];
            $cateIdArr= array_column($cates,'id');
            $cateIds = array_intersect($cateIds,$cateIdArr);
        }
        $attachField = self::getAttachField($module['moduleField']);

        $cateSub = new CategorySubContent();
        if(count($cateIds) == 1){
            $where = [
                'category_id' => $cateIds[0],
                'seller_id' => $param['sellerId'],
            ];
        }else{
            $where = [
                ['category_id','in',$cateIds],
                ['seller_id','=',$param['sellerId']],
            ];
        }

        if($param['offset']>0){
            $count =  $cateSub->where($where)->count();
            $last = bcsub((string)$count,(string)$param['offset']);
            if($last>0){
                $cateSubCon = $cateSub->where($where)->limit($param['offset'],$last)->select()->toArray();
            }else{
                $cateSubCon = [];
            }
        }else{
            $cateSubCon = $cateSub->where($where)->select()->toArray();
        }


//        dd($cateSubCon);
        return self::tagContent($cateSubCon, $param, $attachField);
    }

    /**
     *
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\db\exception\DbException
     */
    public static function tagContent($cateSubCon, $param, $attachField)
    {
        $SubContent = new SubContent();
        if(empty($cateSubCon)){
            if($param['asPage'] == 1 && $param['onlyData']==1){
                return  ['count' => 0, 'data' => []];
            }else if($param['asPage'] == 1 && $param['onlyData'] == 2 ){
                return  $SubContent->where(['id'=>0])->paginate(10);
            }else{
                return  [];
            }
        }else{
            $where = self::setPageWhere($param);
            $subIds = array_column($cateSubCon,'sub_content_id');
            $mainField = $param['mainField'];
            if($param['mainField'] != '*'){
                $mainField = explode(',',$param['mainField']);
                $mainField[] = 'seller_id';
            }
            if(!empty($param['subField'])){
                $subField  = explode(',',$param['subField']);
            }else{
                $subField  = $param['subField'];
            }
            $content = $SubContent->field($mainField);

            $with = [];
            if($mainField == '*' || in_array('thumbnail',$mainField)){
                $with = self::setMainImageWith('thumbnail',$with);
            }
            if($mainField == '*' || in_array('cover',$mainField)){
                $with = self::setMainImageWith('cover',$with);
            }
            if(!empty($with)){
                $content = $SubContent->field($mainField)->with($with);
            }
            $order = self::setOrder($param['sort']);

            $content = $content -> where($where)->whereIn('id',$subIds)->whereTime('publish_time','<=',time())->order($order);
            if($param['asPage'] == 1){
                $page = request()->param('page');
                if($page){
                    $param['page'] = $page;
                }
                $limit = request()->param('limit');
                if($limit){
                    $param['limit'] = $limit;
                }
//                $query = request()->except(['id','cid','page','limit','']);
//
//                if(!empty($query)){
//                    $content->where($query);
//                }
                $content = $content->paginate([
                    'page' => $param['page'],
                    'list_rows' => $param['limit'],
                ]);
            }else{
                if(!empty($param['limit'])){
                    $content->limit((int)$param['limit']);
                }
                $content = $content->select();
            }
            $cateSubCon = getColumnForKeyArray($cateSubCon,'sub_content_id');
            $content->each(function(&$item)use($param,$attachField,$subField,$cateSubCon,$with,$mainField){
                $item['content'] = !empty($item['content'])?htmlspecialchars_decode($item['content']):$item['content'];
                // TODO 版本不同，展示老版本
                if ($item['version'] != $item['show_version']) {
                    $contentHistoryModel = new SubContentHistory();
                    $contentModel = $contentHistoryModel->where([
                        ['sub_content_id', '=', $item['id']],
                        ['version', '=', $item['show_version']]
                    ]);
                    if(!empty($with)){
                        $contentModel = $contentModel->field($mainField)->with($with);
                    }
                    $data = $contentModel->find();
                    if ($data) {
                        $data['id'] = $data['sub_content_id'];
                        $item = $data;
                    }
                }

                $item['category_id'] = $cateSubCon[$item['id']]['category_id'];
                if(!empty($subField)){
                    $subWhere = ['sub_id'=>$item['id'],'seller_id'=>$param['sellerId']];
                    $mainContent = self::$model->getCustomArrayData($subWhere)['data'];
                    $mainContent = self::getMainContent($mainContent,$attachField);
                    $mainContent = $mainContent ?: [];
                    $item['main_content'] = $mainContent;
                }
                if(isset($with['thumbnail'])){
                    $item['thumbnail'] = $item->toArray()['thumbnail'];
                }
                if(isset($with['cover'])){
                    $item['cover'] = $item->toArray()['cover'];
                }
                $item['tag'] = Db::name('tag_sub_content')->alias('a')
                    ->join('tag b', 'b.id = a.tag_id')
                    ->where('a.sub_content_id', '=', $item['id'])
                    ->where('b.is_del',1)
                    ->field('b.*')->select();
            });
            if($param['asPage'] == 1){
                if($param['onlyData'] == 1){
                    return ['total'=>$content->total(),'data'=>$content->all()];
                }else{
                    return $content;
                }
            }else{
                return $content->toArray();
            }
        }
    }

    // 主表附件关联设置
    public static function setMainImageWith($imgKey,$default = ['tag']): array
    {
        $tmpWith =  [
            $imgKey => function($q){
                $q->field('id,name,url,type,description');
            }
        ];
        return array_merge($default,$tmpWith);
    }

    // 查询条件
    public static function setPageWhere($param): array
    {
        $where = [
            'seller_id'=>$param['sellerId'],
            'status' => 1,
            'check_status' => 3,
            'is_del'=>1,
        ];
        if($param['isTop'] != 2){
            $where['is_top'] = 1;
        }
        if($param['isCommend'] != 2){
            $where['is_recommend'] = 1;
        }
        return $where;
    }

    // 排序规则
    public static function setOrder($sort):string
    {
        $defaultOrder = "is_top asc,top_time desc";
        if($sort == 'publish_time desc'){
            $sort = $defaultOrder .',' . $sort;
        }else{
            $sort = $sort . ',' . $defaultOrder;
        }
        return  $sort;
    }

    /**
     *  禁用启用
     */
    public function editStatus($param): array
    {
        $SubContent = new SubContent();
        $where = [
            ['id', 'in', $param['id']],
            ['seller_id', '=', $param['seller_id']],
            ['check_status', '=', 3],
        ];
        $data = [
            'status' => $param['status']
        ];

        return $SubContent->updateSubContent($where,$data);
    }

    /**
     *  置顶
     * @throws ModelException
     */
    public function topOpt($param): \think\response\Json
    {
        $SubContent = new SubContent();
        $where = [
            'id' => $param['id'],
            'seller_id' => $param['seller_id']
        ];
        if($param['is_top'] == 1){
            $top_time = time();
        }else{
            $top_time = 0;
        }
        $data = [
            'is_top' => $param['is_top'],
            'top_time' => $top_time
        ];
        $res = $SubContent->updateSubContent($where,$data);
        return json($res);
    }

    /**
     * 推荐
     * @throws ModelException
     */
    public function recommendAndStatus($param): \think\response\Json
    {
        $SubContent = new SubContent();
        $where = [
            'id' => $param['id'],
            'seller_id' => $param['seller_id']
        ];
        if($param['type'] == 'recommend'){
            $data = [
                'is_recommend' => $param['is_recommend']
            ];
        }else{
            $data = [
                'status' => $param['status']
            ];
        }
        $res = $SubContent->updateSubContent($where,$data);
        return json($res);
    }

    /**
     * 副表内容
     * @throws ModelException
     * @throws ModelEmptyException
     * @throws \think\db\exception\DbException
     */
    public function mainContent($param): \think\response\Json
    {
        $moduleModel = new Module();
        $module = $moduleModel->getCustomArrayData(['id'=>$param['module_id'],'seller_id'=> $param['seller_id']],['moduleField'],'id,table')['data'];
        $table = $module['table'];
        self::setModel($table);
        $Category = new Category();
        $cateWhere = [
            'seller_id' => $param['seller_id'],
            'module_id' => $param['module_id'],
            'website_id' => $param['website_id'],
        ];
        $cateIds= $Category->getColumn($cateWhere)['data'];
        $subCate = new CategorySubContent();
        $field = [];
        foreach($module['moduleField'] as $val){
            if(!empty($val['settings']['relation']) && $val['settings']['relation'] == 'belongs_to_many'){
                continue;
            }else{
                $field[] = $val['table_field'];
            }
        }
        array_unshift($field,'id');
        $subIds =  $subCate->whereIn('category_id',$cateIds)->column('sub_content_id');

        $mainContent = self::$model->field($field)->whereIn('sub_id',$subIds)->paginate($param['limit'])->each(function($item)use($module){
            $attachField = $this->setSpecialField($module['moduleField']);
            self::getSpecialField($item,$attachField);
        });
        return json(['code' => 0, 'msg' => 'ok', 'count' => $mainContent->total(), 'data' => $mainContent->all()]);
    }

    /**
     * 内容新增
     * @throws \app\exception\ModelEmptyException
     * @throws \app\exception\ModelException
     */
    public function createContent($param): \think\response\Json
    {
        $sortField = $this->getContentField($param);
        return jsonReturn(0,'success',$sortField);
    }

    /**
     * 内容新增保存
     * @throws \app\exception\ModelEmptyException
     * @throws \app\exception\ModelException
     * @throws \ReflectionException
     */
    public function saveContent($param): array
    {
        $moduleModel = new Module();
        $module = $moduleModel->getModule(['id'=>$param['module_id'],'seller_id'=> $param['admin']['seller_id']],['moduleField','category'])['data']->toArray();
        $table = $module['table'];
        $cateFlag = $this->verifiedCate($module,$param['category_id']);
        if($cateFlag['code'] != 0){
            return $cateFlag;
        }

        //是否需要审核
        $categoryModel = new Category();
        $needCheckCategoryId = $categoryModel->where([
            ['id', 'in', $param['category_id']],
            ['status', '=', 1],
            ['need_check', '=', 1]
        ])->value('id');

        if ($needCheckCategoryId) {
            $param['check_status'] = 1;
        }

        self::setModel($table);
        // 主表添加记录
        // 生成字段规则验证
        $mainData = $this->setMainContentData($module['id'],$param);
        $className = ClassService::getClassName(self::$model);
        CacheService::deleteRelationCacheByClassName($className);

        Db::startTrans();
        try {
            // 主表记录添加结束
            $content = self::$model->create($mainData);
            $mainId = $content -> id;

            if(!empty(self::$macro)){
                foreach (self::$macro as $macro){
                    if(!empty($mainData[uncamelize($macro)])){
                        $mainData[uncamelize($macro)] = json_decode($mainData[uncamelize($macro)],true);
                        if(is_string($mainData[uncamelize($macro)])){
                            $tmpData = explode(',',$mainData[uncamelize($macro)]);
                        }else{
                            $tmpData = $mainData[uncamelize($macro)];
                        }
                        $content->$macro()->attach($tmpData);
                    }
                }
            }
            // 附表添加记录
            $subContent = new SubContent();
            $subData = $this->getSubData($param,$mainId);
            $subData['module_id'] = $param['module_id'];
            if(empty($subData['seo_title'])){
                $subData['seo_title'] = $subData['title'];
            }
            if(empty($subData['seo_keyword'])){
                $subData['seo_keyword'] = $subData['title'];
            }
            if(empty($subData['seo_description'])){
                $subData['seo_description'] = $this->descExtraction($subData['content']);
            }
            $subRes = $subContent->create($subData);
            $sub_id = $subRes->id;
            // 内链数据
            $inner = Cache::get(md5(strip_tags($param['sub_content']['content'])));
            if(!empty($inner)){
                foreach ($inner as &$val){
                    $val['sub_content_id'] = $sub_id;
                    $val['seller_id'] = $subRes['seller_id'];
                }
                unset($val);
                $innerModel = new InnerChartSubContent();
                $innerModel->saveAll($inner);
            }
            // 关联分类
            $subRes->category()->attach($cateFlag['data'],['seller_id'=>$param['admin']['seller_id']]);
            // 关联标签
            if(!empty($subData['tag'])){
                $tag = $this->dealWithContentTag($subData['tag'],$param['category_id'],$param['admin']['seller_id']);
                $subRes->tag()->attach($tag,['seller_id'=>$param['admin']['seller_id']]);
            }
            // 主表更新记录，添加附表主键
            $content->sub_id = $sub_id;
            $content->save();

            // 审核操作
            if ($needCheckCategoryId && ($content['status'] != 3)) {
                $checkModel = new CategoryCheck();
                $checkList = $checkModel->where([
                    ['seller_id', '=', $param['admin']['seller_id']],
                    ['category_id', '=', $needCheckCategoryId],
                    ['status', '=', 1],
                ])->select()->toArray();

                $checkContentList = [];
                foreach ($checkList as $value) {
                    $users = explode(',', $value['check_users']);
                    foreach ($users as $userId) {
                        $checkContentList[] = [
                            'seller_id' => $param['admin']['seller_id'],
                            'category_check_id' => $value['id'],
                            'real_id' => $sub_id,
                            'check_user_id' => $userId,
                            'step' => $value['step'],
                            'status' => $value['step'] == 1 ? 2 : 1,
                            'examine_mode' => $value['examine_mode']
                        ];
                    }
                }

                $subContentCheckModel = new SubContentCheck();
                $subContentCheckModel->saveAll($checkContentList);

                //写入审核进度
                $checkStepModel = new SubContentCheckStep();
                $checkStepModel->insert([
                    'seller_id' => $param['admin']['seller_id'],
                    'real_id' => $sub_id,
                    'user_id' => $param['admin']['uid'],
                    'content' => '提交审核'
                ]);
                $step1CheckUser = [];
                $version = 1;
                //是自己，直接审核通过
                if (in_array($param['admin']['uid'], $step1CheckUser)) {
                    $newParam['admin'] = $param['admin'];
                    $newParam['real_id'] = $param['id'];
                    $newParam['version'] = $version;
                    $newParam['status'] = 3;
                    $newParam['reason'] = '';
                    $newParam['files'] = '';
                    $res = $this->check($newParam);
                    if ($res['code'] != 0) {
                        throw new Exception($param['id'] . lang("自动审核失败！版本：")."{$version}！" . $res['code'] . $res['msg']);
                    }
                }

            } else {
                //写入审核进度
                $checkStepModel = new SubContentCheckStep();
                $checkStepModel->insert([
                    'seller_id' => $param['admin']['seller_id'],
                    'real_id' => $sub_id,
                    'user_id' => $param['admin']['uid'],
                    'content' => lang('添加内容完成！') . $param['sub_content']['publish_time'] . lang('发布！')
                ]);
            }

            // 操作日志
            optEventLog($sub_id,lang('栏目内容'),lang('添加'));
            Db::commit();
        }catch(\Exception $e){
            Db::rollback();
            return dataReturn(50012,$e->getMessage(), $e->getTrace());
        }
        return dataReturn(0,lang('保存成功'),$subRes);
    }

    /**
     * 内容列表
     * @param $param
     * @return \think\response\Json
     * @throws ModelException
     * @throws \think\db\exception\DbException
     * @throws ModelEmptyException
     */
    public function indexContent($param): \think\response\Json
    {
        $Cate = new Category();
        $cate = $Cate->getAllCustomArrayData(['seller_id'=>$param['seller_id'],'website_id'=>$param['website_id'],'lang'=>$param['lang']],'id asc','id,title,parent_id')['data'];
        if(empty($cate)){
            return json(['code' => 0, 'msg' => 'ok', 'count' => 0, 'data' => []]);
        }
        $cateIds = array_column($cate,'id');
        $cateSub = new CategorySubContent();
        if(empty($param['category_ids'])){
            $cateSubWhere = [
                ['seller_id','=',$param['seller_id']],
                ['category_id','in',$cateIds]
            ];
        }else{
            $param['category_ids'] = array_intersect($param['category_ids'],$cateIds);
            $cateSubWhere = [
                ['seller_id','=',$param['seller_id']],
                ['category_id','in',$param['category_ids']]
            ];
        }
        $cateSubCon = $cateSub->getAllCustomArrayData($cateSubWhere)['data'];
        if(empty($cateSubCon)){
            return json(['code' => 0, 'msg' => lang('成功'), 'count' => 0, 'data' => []]);
        }else{
            $subIds = array_column($cateSubCon,'sub_content_id');
            $SubContent = new SubContent();
            $content = $SubContent->with(['thumbnail'=>function($q){
                $q->field('id,name,url,type,description');
            },'category', 'admin','tag'=>function($query)use($param){
                $query->getQuery()->where(['website_id'=>$param['website_id'],'lang'=>$param['lang']]);
            }])->where(['seller_id'=>$param['seller_id'],'is_del'=> $param['is_del']]);
            if(!empty($param['title'])){
                $content = $content -> whereLike('title','%' . $param['title'] . '%');
            }
            if(!empty($param['where'])) {
                $content = $content -> where($param['where']);
            }
            $data = $content ->whereIn('id',$subIds)
                ->order('id','desc')
                ->field('id,seller_id,category_id,sub_category_ids,module_id,lang,main_id,title,sub_title,thumbnail,hits,admin_id,status,check_status,url as link_url,publish_time,sort,version,show_version,is_del,del_user_id')
                ->paginate($param['limit'])->each(function (&$item)use($param){
                    if(!empty($item['category'])){
                        $Website = new Website();
                        $website = $Website -> getCustomArrayData(['id'=>$param['website_id'],'seller_id'=>$param['seller_id']],'','id,domain')['data'];
                        $item['url'] = 'http://' . $website['domain'] . $item['category'][0]['alias'] . '/' . $item['id'];
                    }
                    $item['check_users'] = ' - - ';
                    if ($item['check_status'] != 3) {
                        // 查询当前审核人
                        $contentCheckModel = new SubContentCheck();
                        $checkUsers = $contentCheckModel->where([
                            'real_id' => $item['id'],
                            'status' => 2,
                            'version' => $item['version'],
                            'seller_id' => $param['seller_id']
                        ])->with(['admin'])->select()->toArray();
                        $checkUsers = array_column($checkUsers, 'name');
                        $item['check_users'] = implode(',', $checkUsers);
                    }
                    $item['del_user'] = '';
                    if ($item['del_user_id'] > 0 && $item['is_del'] == 2) {
                        $adminModel = new Admin();
                        $item['del_user'] = $adminModel->where('id', $item['del_user_id'])->value('name');
                    }

                    $item['new_status'] = self::getNewStatus($item);
                });
            return json(['code' => 0, 'msg' => lang('成功'), 'count' => $data->total(), 'data' => $data->all()]);
        }
    }

    public static function getNewStatus($item): int
    {
        $newStatus = 0;
        if ($item['status'] == 1) {
            if ($item['check_status'] == 1 || $item['check_status'] == 2) {
                $newStatus = 3;
            } elseif ($item['check_status'] == 3 && $item['publish_time'] <= date('Y-m-d H:i:s')) {
                $newStatus = 1;
            } elseif ($item['check_status'] == 3 && $item['publish_time'] > date('Y-m-d H:i:s')) {
                $newStatus = 2;
            } else {
                $newStatus = 4;
            }
        } else if ($item['status'] == 2) {
            $newStatus = 5;
        } else {
            $newStatus = 6;
        }
        return $newStatus;
    }

    /**
     * 上一篇
     * @throws ModelException
     * @throws ModelEmptyException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\db\exception\DbException
     */
    public static function getPreContent($param)
    {
        $cate = self::getCacheCate($param['cid'],$param['seller_id'],$param['website_id'],$param['lang']);
        try {
            $subContent = self::getAnotherContentDetail($cate['id'],$param['id'],$param['seller_id'],'<');
            if(empty($subContent)){
                $cateIds = self::getAllCateIds($param['seller_id'],$param['cid'],$param['website_id'],$param['lang']);
                if(count($cateIds) > 1){
                    $subContent = self::getAnotherContentDetail($cateIds,$param['id'],$param['seller_id'],'<');
                }
            }
        }catch (ModelEmptyException $me){
            throw new ModelEmptyException();
        } catch (\Exception $e){
            throw new ModelException();
        }
        return $subContent;
    }

    /**
     * 下一篇
     * @throws ModelException
     * @throws ModelEmptyException
     */
    public static function getNextContent($param)
    {
        $cate = self::getCacheCate($param['cid'],$param['seller_id'],$param['website_id'],$param['lang']);
        try {
            $subContent = self::getAnotherContentDetail($cate['id'],$param['id'],$param['seller_id']);
            if(empty($subContent)){
                $cateIds = self::getAllCateIds($param['seller_id'],$param['cid'],$param['website_id'],$param['lang']);
                if(count($cateIds) > 1){
                    $subContent = self::getAnotherContentDetail($cateIds,$param['id'],$param['seller_id']);
                }
            }
        }catch (ModelEmptyException $me){
            throw new ModelEmptyException();
        } catch (\Exception $e){
            throw new ModelException();
        }
        return $subContent;
    }

    /**
     * @throws ModelException
     * @throws ModelEmptyException
     */
    public static function getCacheCate($cid, $sellerId, $siteId, $lang)
    {
        $category = new Category();
        $cate = $category -> getCustomArrayData([
            ['id','=',$cid],
            ['seller_id','=',$sellerId],
            ['website_id','=',$siteId],
            ['lang','=',$lang],
        ],['module'],'id,module_id')['data'];
        $table = $cate['module']['table'];
        self::setModel($table);
        return $cate;
    }

    /**
     * @throws ModelException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\db\exception\DbException
     * @throws ModelEmptyException
     */
    public static function getAnotherContentDetail($cateId, $id, $sellerId, $flag = '>')
    {
        $SubContent = new SubContent();
        $cateSub = new CategorySubContent();
        if(is_array($cateId)){
            $cateSubCon = $cateSub->getAllCategorySubContent([['category_id','in',$cateId]])['data'];
        }else{
            $cateSubCon = $cateSub->getAllCategorySubContent(['category_id'=>$cateId])['data'];
        }
        $subIds = array_column($cateSubCon,'sub_content_id');
        $where = [
            ['id',$flag,$id],
            ['id','in',$subIds],
            ['seller_id','=',$sellerId],
            ['status','=',1],
            ['check_status', '=', 3],
            ['is_del','=',1],
        ];

        $order = 'id desc';
        if ($flag == '>') {
            $order = 'id asc';
        }
        return $SubContent->with(['thumbnail'=>function($q){
            $q->field('id,name,url,type,description');
        },'cover'=>function($q){
            $q->field('id,name,url,type,description');
        }])->where($where)->whereTime('publish_time','<',time())->order($order)->find();

    }

    /**
     * 获取所有的子孙分类Id
     * @throws ModelEmptyException
     * @throws ModelException
     */
    public static function getAllCateIds($sellerId, $pid, $siteId, $lang): array
    {
        $Category = new Category();
        $cate = $Category->getCustomArrayData(['id'=>$pid,'seller_id'=>$sellerId,'website_id'=>$siteId,'lang'=>$lang])['data'];
        $parentPath = $cate['path'] . $cate['id'] . '-';
        $categories = $Category->getAllCustomArrayData([['path','like',$parentPath . '%'],['seller_id','=',$sellerId],['website_id','=' ,$siteId],['lang','=',$lang]])['data'];
        $categories[] = $cate;
        return array_column($categories,'id');
    }

    /**
     * 前台详情
     * @param $param
     * @return mixed
     * @throws ModelEmptyException
     * @throws ModelException
     */
    public function getContentDetail($param)
    {
        $cate = $param['cate'];
        $table = $cate['module']['table'];
        self::setModel($table);
        try {
            $SubContent = new SubContent();
            $where = [
                ['id','=',$param['id']],
                ['seller_id','=',$param['seller_id']],
                ['publish_time','<',date('Y-m-d H:i:s',time())],
                ['status','=',1],
                ['is_del','=',1],
                ['check_status','=',3],
                ['show_version', '=', Db::raw('version')]
            ];
            $subContent = $SubContent->getSubContent($where,['thumbnail'=>function($q){
                $q->field('id,name,url,type,description');
            },'cover'=>function($q){
                $q->field('id,name,url,type,description');
            },'tag'=>function($query)use($param){
                $query->getQuery()->where(['website_id'=>$param['website_id'],'lang'=>$param['lang']]);
            }])['data'];
            $article = self::$model->where(['sub_id' => $param['id'], 'seller_id' => $param['seller_id']])->find();
            if(empty($article)){
                throw new ModelEmptyException();
            }
            $attachField = $this->setSpecialField($cate['module']['moduleField']);

            $this->getSpecialField($article,$attachField);
            $subContent['main_content'] = $article;



        }catch (ModelEmptyException $me){
            throw new ModelEmptyException();
        } catch (\Exception $e){
            throw new ModelException();
        }
        return $subContent;
    }

    /**
     * 内容详情
     * @throws \app\exception\ModelEmptyException
     * @throws ModelException
     */
    public function readContent($param): \think\response\Json
    {
        $moduleModel = new Module();
        $module = $moduleModel->getModule(['id'=>$param['module_id'],'seller_id'=> $param['seller_id']],['moduleField'])['data']->toArray();
        $table = $module['table'];
        self::setModel($table);
        try {
            $SubContent = new SubContent();
            $subContent = $SubContent->getSubContent(['id'=>$param['id'],'seller_id'=>$param['seller_id'],'is_del'=>1],['thumbnail'=>function($q){
                $q->field('id,name,url,type,description');
            },'cover'=>function($q){
                $q->field('id,name,url,type,description');
            },'category','admin','tag'=>function($query)use($param){
                $query->getQuery()->where(['website_id'=>$param['website_id'],'lang'=>$param['lang']]);
            }])['data']->toArray();
            $article = self::$model->where(['sub_id' => $param['id'], 'seller_id' => $param['seller_id']])->find();

            if(empty($article)){
                throw new ModelEmptyException();
            }

            $cate = $subContent['category'];
            if(!empty($cate)){
                $cateIds = array_column($cate,'id');
                $subContent['category'] = $cateIds;
                $siteIds = array_values(array_unique(array_column($cate,'website_id')));
                $subContent['website'] = $siteIds;
            }
            $tag = $subContent['tag'];
            if(!empty($tag)){
                $tagIds = implode(',',array_column($tag,'title'));
                $subContent['tag'] = $tagIds;
            }else{
                $subContent['tag'] = '';
            }
            $attachField = $this->setSpecialField($module['moduleField']);
            $this->getSpecialField($article,$attachField);

            $subContent['main_content'] = $article;

            $subContent['new_status'] = self::getNewStatus($subContent);

            //获取文章审核流程列表
            $checkStepList = [];
            if ($subContent['check_status'] != 3) {
                $checkStepModel = new SubContentCheckStep();
                $checkStepList = $checkStepModel->alias('a')
                    ->with(['admin'])
                    ->join('sub_content_check b', 'a.check_id = b.id and b.status != 5', 'left')
                    ->where([
                        'a.real_id' => $subContent['id'],
                    ])->field('a.*, b.status, b.reason, b.files')->select()->toArray();

                foreach ($checkStepList as &$value) {
                    $value['file_list'] = [];
                    if (!empty($value['files'])) {
                        $attachmentModel = new Attachment();
                        $value['file_list'] = $attachmentModel->where([['id', 'in', $value['files']]])->select();
                    }
                    $value['name'] = $value['admin']['name'] ?? '';
                }

                if ($subContent['check_status'] == 4) {
                    // 待修改提醒
                    $checkStepList[] = [
                        'content' => lang('待修改'),
                        'name' => $subContent['admin']['name'],
                        'create_time' => '',
                    ];
                } else {
                    // 待审核人
                    $contentCheckModel = new SubContentCheck();
                    $list = $contentCheckModel->with(['admin'])->where([
                        ['real_id', '=', $subContent['id']],
                        ['status', '=', 2],
                        ['version', '=', $subContent['version']]
                    ])->select()->toArray();
                    $nameArr = [];
                    foreach ($list as $v) {
                        if (!empty($v['name'])) {
                            $nameArr[] = $v['name'];
                        }
                    }

                    $checkStepList[] = [
                        'content' => lang('待审核'),
                        'name' => implode(',', $nameArr),
                        'create_time' => '',
                    ];
                }

            }
            $subContent['check_step_list'] = $checkStepList;

            if (!empty($subContent['content'])) {
                $subContent['content'] = htmlspecialchars_decode($subContent['content']);
            }
        }catch (ModelEmptyException $me){
            return jsonReturn(-1,  $me->getMessage(), $me->getTrace());
            throw new ModelEmptyException();
        } catch (\Exception $e){
            return jsonReturn(-1, $e->getMessage(), $e->getTrace());
            throw new ModelException();
        }
        $contentField = $this->getModuleField($param);
        return jsonReturn(0,lang('成功'),[
            'field' => $contentField,
            'content' => $subContent
        ]);
    }

    /**
     * 获取附件字段
     * @param $moduleField
     * @return array[]
     */
    public static function getAttachField($moduleField): array
    {
        return self::setSpecialField($moduleField);
    }

    /**
     * @param $article
     * @param $attachField
     * @return mixed
     */
    public static function getMainContent($article, $attachField)
    {
        return self::getSpecialField($article,$attachField);
    }

    public static function getSpecialField(&$article,$attachField)
    {
        $article = self::getAttachPath($article,$attachField);
        if(!empty(self::$hasOne)){
            foreach(self::$hasOne as $hasOne){
                $article[$hasOne['local_key']] = self::getHasOneData($hasOne['table'],$hasOne['foreign_key'],$article[$hasOne['local_key']],$article['seller_id']);
            }
        }

        if(!empty(self::$belongsTo)){
            foreach(self::$belongsTo as $belong){
                $article[$belong['local_key']] = self::getHasOneData($belong['table'],$belong['foreign_key'],$article[$belong['local_key']],$article['seller_id']);
            }
        }
        if(!empty(self::$hasMany)){
            foreach(self::$hasMany as $hasMany){
                $article[$hasMany['local_key']] = self::getHasManyData($hasMany['table'],$hasMany['foreign_key'],$article[$hasMany['local_key']],$article['seller_id']);
            }
        }

        if(!empty(self::$macro)){
            foreach(self::$macro as $macro){
                $article[uncamelize($macro)] = $article->$macro()->select()->toArray();
            }
        }
        return $article;
    }

    /**
     * 内容删除
     * @param $param
     * @return \think\response\Json
     */
    public function deleteContent($param): \think\response\Json
    {
        $module = $this->getModule($param['module_id'], $param['seller_id']);
        $table = $module['table'];
        self::setModel($table);
        Db::startTrans();
        try{
            $SubContent = new SubContent();
            $subContent = $SubContent->where(['id'=>$param['id'],'seller_id'=>$param['seller_id'],'is_del'=>1])->find();
            if(empty($subContent)){
                return jsonReturn(0,lang('删除成功'),$subContent);
            }
            // 主表软删
            $subContent->is_del = 2;
            $subContent->del_user_id = $param['admin_id'];
            $subContent->delete_time = time();
            $subContent->update_time = time();
            $subContent->save();
            $className = ClassService::getClassName(self::$model);
            CacheService::deleteRelationCacheByClassName($className);
            // 副表软删
            $content = self::$model->where(['sub_id'=>$param['id'],'seller_id'=>$param['seller_id']])->find();
            if(!empty($content)){
                $content->is_del = 2;
                $content->delete_time = time();
                $content->update_time = time();
                $content->save();
            }

            // 复制删除内容到回收站表
            $recycleBin = new RecycleBin();
            $binData = [
                'seller_id' => $param['seller_id'],
                'object_id' => $content ? $content['id'] : 0,
                'sub_id' => $subContent['id'],
                'module_id' => $param['module_id'],
                'table_name' => $module['title'].'-'.$module['table'],
                'title' => !empty($subContent['title']) ? $subContent['title'] : $module['title'].'内容',
                'admin_id' => $param['admin_id'],
                'name' => $param['name'],
            ];
            $recycleBin -> addRecycleBin($binData);
            // 操作日志
            optEventLog($subContent['id'],lang('栏目内容'),lang('删除'));
            Db::commit();
        }catch (\Exception $e){
            Db::rollback();
            return jsonReturn(50025,$e->getMessage());
        }
        return jsonReturn(0,lang('删除成功'),$content);
    }

    /**
     * 更新内容
     * @throws ModelException
     * @throws ModelEmptyException
     */
    public function updateContent(&$param): \think\response\Json
    {
        $module = $this->getModule($param['module_id'], $param['admin']['seller_id']);
        $table = $module['table'];
        self::setModel($table);
        $cateFlag = $this->verifiedCate($module,$param['category_id']);
        if($cateFlag['code'] != 0){
            return json($cateFlag);
        }
        $contentModel = new SubContent();
        // 内容历史
        $oldContentData = $contentModel->where('id', $param['id'])->find()->toArray();

        //编辑后版本号+1
        $contentModel->where('id', $param['id'])->update(['version' => Db::raw('version + 1')]);

        $content = self::$model->with('subContent.category')->where(['sub_id'=>$param['id'],'seller_id'=>$param['admin']['seller_id']])->find();
        if(empty($content)){
            return jsonReturn(40004,lang('内容不存在'));
        }

        //是否需要审核,不需要审核直接通过，版本号为当前版本号，
        $categoryModel = new Category();
        $needCheckCategoryId = $categoryModel->where([
            ['id', 'in', $param['category_id']],
            ['status', '=', 1],
            ['need_check', '=', 1]
        ])->value('id');

        if ($needCheckCategoryId) {
            $param['check_status'] = 1;
        } else {
            $param['check_status'] = 3;
        }

        $subContent = $content['subContent'];
        // 主表添加记录
        // 生成字段规则验证
        $param['main_id'] = $content['id'];
        $mainData = $this->setMainContentData($module['id'],$param,true);
        Db::startTrans();
        try {
            // 主表更新内容
            $res = $content->saveAll([$mainData]);
            $mainId = $content -> id;
            $className = ClassService::getClassName(self::$model);
            CacheService::deleteRelationCacheByClassName($className);

            if(!empty(self::$macro)){
                foreach (self::$macro as $macro){
                    $content->$macro()->detach();
                    $mainData[uncamelize($macro)] = json_decode($mainData[uncamelize($macro)],true);
                    if(is_string($mainData[uncamelize($macro)])){
                        $tmpData = explode(',',$mainData[uncamelize($macro)]);
                    }else{
                        $tmpData = $mainData[uncamelize($macro)];
                    }
                    $content->$macro()->attach($tmpData);
                }
            }
            // 附表添加记录
            $param['sub_id'] = $content['subContent']['id'];
            $subData = $this->getSubData($param,$mainId,true);
            $subContent->saveAll([$subData]);
            $subContent->category()->detach();
            $subContent->category()->attach($cateFlag['data'],['seller_id'=>$param['admin']['seller_id']]);
            // 关联标签
            if(!empty($subData['tag'])){
                $tag = $this->dealWithContentTag($subData['tag'],$param['category_id'],$param['admin']['seller_id']);
                $subContent->tag()->detach();
                $subContent->tag()->attach($tag,['seller_id'=>$param['admin']['seller_id']]);
            }

            $version = $content['subContent']['version'];

            //添加内容历史
            $contentHistoryModel = new SubContentHistory();
            $oldContentData['sub_content_id'] = $oldContentData['id'];
            unset($oldContentData['id'],$oldContentData['show_version']);
            $oldContentData['create_time'] = strtotime($oldContentData['create_time']);
            $oldContentData['update_time'] = strtotime($oldContentData['update_time']);
            $contentHistoryModel->insert($oldContentData);

            // 审核操作
            if ($needCheckCategoryId  && ($content['status'] != 3)) {
                $checkModel = new CategoryCheck();
                $checkList = $checkModel->where([
                    ['seller_id', '=', $param['admin']['seller_id']],
                    ['category_id', '=', $needCheckCategoryId],
                    ['status', '=', 1],
                ])->select()->toArray();

                $checkContentList = [];

                $step1CheckUser = [];
                foreach ($checkList as $value) {
                    $users = explode(',', $value['check_users']);
                    foreach ($users as $userId) {
                        $checkContentList[] = [
                            'seller_id' => $param['admin']['seller_id'],
                            'category_check_id' => $value['id'],
                            'real_id' => $param['id'],
                            'check_user_id' => $userId,
                            'step' => $value['step'],
                            'status' => $value['step'] == 1 ? 2 : 1,
                            'version' => $version,
                            'examine_mode' => $value['examine_mode']
                        ];
                        if ($value['step'] == 1) {
                            $step1CheckUser[] = $userId;//第一步审核人中是或签且有自己，直接审核通过
                        }
                    }
                }

                $subContentCheckModel = new SubContentCheck();
                //原审核作废
                $subContentCheckModel->where([
                    ['seller_id', '=', $param['admin']['seller_id']],
                    ['real_id', '=', $param['id']],
                    ['version', '=', $oldContentData['version']],
                    ['status', 'in', [1,2]],
                ])->update(['status' => 5]);

                //开启新审核
                $subContentCheckModel->saveAll($checkContentList);

                //写入审核进度
                $checkStepModel = new SubContentCheckStep();
                $checkStepModel->insert([
                    'seller_id' => $param['admin']['seller_id'],
                    'real_id' => $param['id'],
                    'user_id' => $param['admin']['uid'],
                    'content' => lang('修改完成，提交审核')
                ]);

                //是自己，直接审核通过
                if (in_array($param['admin']['uid'], $step1CheckUser)) {
                    $newParam['admin'] = $param['admin'];
                    $newParam['real_id'] = $param['id'];
                    $newParam['version'] = $version;
                    $newParam['status'] = 3;
                    $newParam['reason'] = '';
                    $newParam['files'] = '';
                    $res = $this->check($newParam);
                    if ($res['code'] != 0) {
                        throw new Exception($param['id'] . lang('自动审核失败！版本：')."{$version}！" . $res['code'] . $res['msg']);
                    }
                }

            } else {
                $contentModel->where('id', $param['id'])->update(['show_version' => Db::raw('version')]);
                //写入审核进度
                $checkStepModel = new SubContentCheckStep();
                $checkStepModel->insert([
                    'seller_id' => $param['admin']['seller_id'],
                    'real_id' => $param['id'],
                    'user_id' => $param['admin']['uid'],
                    'content' => lang('编辑成功')
                ]);
            }

            // 操作日志
            optEventLog($param['sub_id'],lang('栏目内容'),lang('更新'));
            Db::commit();
        }catch(\Exception $e){
            Db::rollback();
            return jsonReturn(50012,$e->getMessage(), $e->getTrace());
        }
        return jsonReturn(0,lang('保存成功'),$res);

    }

    /**
     * 审核
     * @return array
     */
    public function check($param)
    {
        $where = [
            'seller_id' => $param['admin']['seller_id'],
            'real_id' => $param['real_id'],
            'check_user_id' => $param['admin']['uid'],
            'status' => 2,
            'version' => $param['version'],
        ];
        $contentCheckModel = new SubContentCheck();
        $checkInfo = $contentCheckModel->where($where)->findOrEmpty();

        if (!isset($checkInfo['id'])) {
            return dataReturn(-2, lang('待审核信息不存在'));
        }

        Db::startTrans();
        try {
            $data = $param;
            unset($data['admin']);
            $res = $contentCheckModel->where(['id' => $checkInfo['id']])->update($data);
            if ($res === false) {
                throw new Exception(lang('审核失败！'));
            }
            // 总共有几次审核
            $maxStep = $contentCheckModel->where([
                'seller_id' => $param['admin']['seller_id'],
                'real_id' => $param['real_id'],
                'version' => $param['version'],
            ])->order('step desc')->value('step');

            if ($param['status'] == 3) {
                // 通过
                $content = lang('审核通过');
            } else {
                // 拒绝
                $content = lang('审核驳回');

                //后续审核作废
                $orWhere = [
                    ['seller_id', '=', $param['admin']['seller_id']],
                    ['real_id', '=', $param['real_id']],
                    ['step', '>', $checkInfo['step']],
                    ['version', '=', $param['version']],
                ];
                $contentCheckModel->updateCustomData($orWhere, ['status' => 5]);
            }

            //保存当前审核数据
            $updateData = [
                'status' => $param['status'],
                'reason' => $param['reason'],
                'files' => $param['files'],
                'oper_user_id' => $param['admin']['uid'],
            ];
            $contentCheckModel->updateCustomData($where, $updateData);

            if ($checkInfo['examine_mode'] == 1) {
                //或签 , 当前这步其他人的操作自动审核
                $orWhere = [
                    'seller_id' => $param['admin']['seller_id'],
                    'real_id' => $param['real_id'],
                    'status' => 2,
                    'examine_mode' => 1,
                    'step' => $checkInfo['step'],
                    'version' => $param['version'],
                ];
                $contentCheckModel->updateCustomData($orWhere, $updateData);

                //激活下一步
                $nextWhere = [
                    'seller_id' => $param['admin']['seller_id'],
                    'real_id' => $param['real_id'],
                    'status' => 1,
                    'step' => $checkInfo['step'] + 1,
                    'version' => $param['version'],
                ];
                $contentCheckModel->updateCustomData($nextWhere, ['status' => 2]);
            }

            //写入审核进度
            $checkStepModel = new SubContentCheckStep();
            $checkStepModel->insert([
                'seller_id' => $param['admin']['seller_id'],
                'real_id' => $param['real_id'],
                'user_id' => $param['admin']['uid'],
                'check_id' => $checkInfo['id'],
                'content' => $content
            ]);

            $subContentModel = new SubContent();
            if ($maxStep == $checkInfo['step'] || $param['status'] == 4) {
                // 已经是最后一步审核了且审核通过了  或某一步被审核拒绝了，更新内容数据为相应状态
                $subContentModel->where('id', $param['real_id'])->update(['check_status' => $param['status'], 'show_version' => $param['version']]);
            } else {
                // 更新内容数据为审核中
                $subContentModel->where('id', $param['real_id'])->where('check_status', 1)->update(['check_status' => 2]);
            }
        } catch (\Exception $e) {
            Db::rollback();
            return dataReturn(-3, $e->getMessage(), $e->getTrace());
        }
        Db::commit();
        return dataReturn(0, lang('操作成功'));
    }

    /**
     * @throws \Exception
     */
    public function dealWithContentTag($tagParam, $cateParam, $sellerId = 1): array
    {
        // 关联标签
        if(is_string($tagParam)){
            $tag = explode(',',$tagParam);
        }else{
            $tag = $tagParam;
        }
        $Category = new Category();
        $category = $Category -> getAllCustomArrayData([['id','in',$cateParam]])['data'];
        $lang = array_column($category,'lang')[0];
        $siteId = array_unique(array_column($category,'website_id'));
        $Tag = new Tag();
        $tagList = $Tag -> getAllCustomArrayData([['seller_id','=',$sellerId],['website_id','in',$siteId],['title','in',$tag]])['data'];
        $tagUniqueFlag = array_column($tagList,'unique_tag');
        $tagList = getColumnForKeyArray($tagList,'unique_tag');
        $tagIds = [];
        $pinyin = new Pinyin();
        $diffData = [];
        foreach ($tag as $val) {
            $tmp = [
                'seller_id' => $sellerId,
                'website_id' => '',
                'lang' => $lang,
                'title' => $val,
                'first_letter' => substr(strtoupper($pinyin->abbr($val,PINYIN_KEEP_ENGLISH)),0,1),
                'seo_title' => $val,
                'seo_keywords' => $val,
                'seo_description' => $val
            ];
            foreach ($siteId as $vv){
                $tmp['website_id'] = $vv;
                $tmpUnique = $tmp['seller_id'] . '-' . $vv . '-' . $lang .'-'.$tmp['title'];
                if(!in_array($tmpUnique,$tagUniqueFlag)){
                    $tmp['unique_tag'] = $tmpUnique;
                    $diffData[] = $tmp;
                }else{
                    $tagIds[] = $tagList[$tmpUnique]['id'];
                }
            }
        }
        $tag =  $Tag->saveAll($diffData);

        $tmpIds = [];
        foreach ($tag as $item){
            $tmpIds[] = (int)$item->id;
        }
        return array_merge($tagIds,$tmpIds);
    }

    /**
     * 设置主表内容
     * @param $moduleId
     * @param $param
     * @param false $isEdit
     * @return mixed|\think\response\Json
     * @throws ModelException
     * @throws \Exception
     */
    public function setMainContentData($moduleId, $param, bool $isEdit = false)
    {
        $moduleField = new ModuleField();
        $field = $moduleField->getModuleFieldList(['module_id'=>$moduleId,'seller_id'=>$param['admin']['seller_id']])['data']->toArray();

        $fieldArr = [];

        $rule = [];
        $arrayFieldKey=[];
        foreach ($field as $val){
            if(!empty($val['validate_rule'])){
                $rule_key = $val['table_field'] .'|'. $val['form_title'];
                $rule[$rule_key] = $val['validate_rule'];
            }
            if(in_array($val['type'],self::$arrayField)){
                $rule_key = $val['table_field'] .'|'. $val['form_title'];
                $rule[$rule_key] = 'array';
                array_push($arrayFieldKey,$val['table_field']);
            }
            if($val['type'] == '关联字段' && $val['settings']['relation'] == 'belongs_to_many'){
                $middle = $val['settings']['local_table'] . '_' . $val['settings']['table'];
                $func = camelize($val['table_field']);
                $foreign_key = $val['settings']['table'] . '_' . $val['settings']['foreign_key'];
                $local_key = $val['settings']['local_table'] . '_' . $val['settings']['local_key'];
                $this->setRelation($func,$val['settings']['table'],$middle,$foreign_key,$local_key);
            }
            if($val['type'] == '关联字段' && ($val['settings']['relation'] == 'has_many' || $val['settings']['relation'] == 'belongs_to_many')){
                array_push($arrayFieldKey,$val['table_field']);
            }
            $fieldArr[] = $val['table_field'];
        }

        // 验证数据
        if(!empty($rule)){
            try{
                validate($rule)->check($param['main_content']);
            }catch (ValidateException $e){
                throw new \Exception($e->getError(),-422);
            }
        }
        $mainData = $param['main_content'];

        foreach ($fieldArr as $field) {
            if(in_array($field,$arrayFieldKey)){
                if (!empty($mainData[$field])) {
                    $mainData[$field] = json_encode($mainData[$field]);
                } else {
                    $mainData[$field] = '';
                }
            }
        }

        $mainData['lang'] = $param['lang'] ?? config('lang.default_lang');
        $mainData['seller_id'] = $param['admin']['seller_id'];
        if($isEdit){
            $mainData['id'] = $param['main_id'];
        }
        return $mainData;
    }

    /**
     * 验证分类
     * @param $module
     * @param $categoryIds
     * @return array
     */
    public function verifiedCate($module,$categoryIds): array
    {
        if(empty($module['category'])){
            $cateIds = [];
        }else{
            $cateIds = (new Category())->where([
                ['module_id', '=', $module['id']],
            ])->column('id');
//            $cateIds = array_column($module['category'],'id');
            $cateFlag = array_diff($categoryIds,$cateIds);
        }
        if(empty($cateIds) || !empty($cateFlag)){
            return dataReturn(50029,lang('有栏目数据不属于该模型,请重新选择'));
        }
        return dataReturn(0,'success',$categoryIds);
    }

    /**
     * 获取特殊字段（附件+关联关系字段+数组格式转换字段）
     * @param $param
     * @return array
     */
    public static function setSpecialField($param): array
    {
        // 单附件
        $singleField = [];
        // 多附件
        $multiField = [];
        // 格式转化字段
        $arrField = [];
        // 富文本字段
        $richTextField = [];

        foreach($param as $item){
            if ($item['form_type'] == 'richText') {
                $richTextField[] = $item['table_field'];
            }
            if(in_array($item['form_type'],['image','video','file'])){
                $singleField[] = $item['table_field'];
            }
            if(in_array($item['form_type'],['multiImage','multiVideo','multiFile'])){
                $multiField[] = $item['table_field'];
            }
            if($item['form_type'] == 'reference'){
                if($item['settings']['relation'] == 'has_one'){
                    $func = camelize($item['table_field']);
                    $tmp = [
                        // 关联方法
                        'func_name' => $func,
                        'table' => $item['settings']['table'],
                        'local_key' => $item['settings']['local_key'],
                        'foreign_key' => $item['settings']['foreign_key'],
                    ];
                    self::$hasOne[$item['table_field']] = $tmp;
                }

                if($item['settings']['relation'] == 'belongs_to'){
                    $func = camelize($item['table_field']);
                    $tmp = [
                        // 关联方法
                        'func_name' => $func,
                        'table' => $item['settings']['table'],
                        'local_key' => $item['settings']['local_key'],
                        'foreign_key' => $item['settings']['foreign_key'],
                    ];
                    self::$belongsTo[$item['table_field']] = $tmp;
                }

                if($item['settings']['relation'] == 'has_many'){
                    $tmp = [
                        // 关联方法
                        'func_name' => camelize($item['table_field']),
                        'table' => $item['settings']['table'],
                        'local_key' => $item['settings']['local_key'],
                        'foreign_key' => $item['settings']['foreign_key'],
                    ];
                    self::$hasMany[$item['table_field']] = $tmp;
                }
                if($item['settings']['relation'] == 'belongs_to_many'){

                    $middle = $item['settings']['local_table'] . '_' . $item['settings']['table'];
                    $foreign_key = $item['settings']['table'] . '_' . $item['settings']['foreign_key'];
                    $local_key = $item['settings']['local_table'] . '_' . $item['settings']['local_key'];
                    self::setRelation(camelize($item['table_field']),$item['settings']['table'],$middle,$foreign_key,$local_key);
                }
            }
            if(in_array($item['form_type'],['dateTimeRange','multiSelect','checkbox'])){
                $arrField[] = $item['table_field'];
            }
        }
        return [
            'single' => $singleField,
            'multi' => $multiField,
            'arrField' => $arrField,
            'richTextField' => $richTextField,
        ];
    }

    /**
     * 获取附件链接
     */
    public static function getAttachPath($item, $attachField)
    {
        $attachment = new Attachment();

        // 富文本
        if (count($attachField['richTextField'])) {
            foreach($attachField['richTextField'] as $val){
                $item[$val] = htmlspecialchars_decode($item[$val]);
            }
        }

        // 单附件
        if(count($attachField['single'])){
            $singleIds = [];
            $singleField = [];
            foreach($attachField['single'] as $val){
//                if($item[$val]){
                $singleIds[] = $item[$val];
                $singleField[$val] = $item[$val];
//                }
            }
            $singleAttach = $attachment ->getAllCustomArrayData([['id','in',$singleIds]],'id desc','id,name,url,type,description')['data'];
            $singleAttach = getColumnForKeyArray($singleAttach,'id');
            if(!empty($singleAttach)){
                foreach ($singleField as $kk => $vv){
                    if($vv == 0 || !isset($singleAttach[$vv])){
                        $item[$kk] = null;
                    }else{
                        $item[$kk] = $singleAttach[$vv];
                    }
                }
            }

        }

        // 多附件
        if(count($attachField['multi'])){
            $idStr = [];
            $multiFields = [];
            foreach($attachField['multi'] as $multi){
                if($item[$multi]){
                    $idArr = json_decode($item[$multi],true);
                    $multiFields[$multi] = $idArr;
                    $idStr = array_merge($idStr,$idArr);
                }else{
                    $item[$multi] = [];
                }
            }
            if(!empty($idStr)){
                $multiIds = array_unique($idStr);
                $multiAttach =$attachment ->getAllCustomArrayData([['id','in',$multiIds]],'id desc','id,name,url,type,description')['data'];

                $multiAttach = getColumnForKeyArray($multiAttach,'id');
                foreach($multiFields as $km => $vm){
                    $attachments = [];
                    if(!empty($multiAttach)){
                        foreach ($vm as $vvm) {
                            if(isset($multiAttach[intval($vvm)])){
                                $attachments[] = $multiAttach[intval($vvm)];
                            }
                        }
                    }
                    $item[$km] = $attachments;
                }
            }
        }
        // 数组转化字段
        if(count($attachField['arrField'])){
            foreach($attachField['arrField'] as $ak => $ar){
                if(!empty($ar)){
                    if(empty($item[$ar])){
                        $item[$ar] = [];
                    }else{
                        $item[$ar] = json_decode($item[$ar],true);
                    }
                }
            }
        }
        return $item;
    }

    /**
     * 获取一对一关联数据
     * @param $relationTable
     * @param $key
     * @param $val
     * @param string $field
     * @param int $sellerId
     * @return mixed
     */
    public static function getHasOneData($relationTable, $key, $val, int $sellerId,string $field = '*')
    {
        $model = self::getRelationModel($relationTable);
        return $model->getCustomArrayData([[$key,'=',$val,'seller_id','=',$sellerId]],[],$field)['data'];
    }

    /**
     * 获取多对多关联数据
     * @param $relationTable
     * @param $key
     * @param $val
     * @param string $field
     * @param int $sellerId
     * @return mixed
     */
    public static function getHasManyData($relationTable, $key, $val, int $sellerId,string $field = '*')
    {
        $model = self::getRelationModel($relationTable);
        $tmpData = [];
        if($val){
            $tmpData = json_decode($val,true);
        }
        return $model -> getAllCustomArrayData([[$key,'in',$tmpData,'seller_id','=',$sellerId]],[],$field)['data'];
    }

    /**
     * @throws ModelEmptyException
     * @throws ModelException
     */
    public static function getRelationModel($relationTable)
    {
        $modelName = '\\app\\model\\' . ucfirst(camelize($relationTable));
        $module = new Module();
        $tableFlag = $module->getCustomArrayData(['table'=>$relationTable])['data'];
        if(!empty($tableFlag)){
            $modelName = '\\app\\model\\customModel\\' . ucfirst(camelize($relationTable));
        }
        return new $modelName();
    }

    /**
     * 设置模型关联关系
     * @param Model $model
     * @param array $assocField
     * @throws ModelEmptyException
     * @throws ModelException
     */
    public static function setRelation($func,$table,$middle,$foreign_key,$local_key)
    {
        $modelName = '\\app\\model\\' . ucfirst(camelize($table));
        $module = new Module();
        $tableFlag = $module->getCustomArrayData(['table'=>$table])['data'];
        if(!empty($tableFlag)){
            $modelName = '\\app\\model\\customModel\\' . ucfirst(camelize($table));
        }
        self::$macro[] = $func;
        $closure = function ()use($modelName,$middle,$foreign_key,$local_key){
            return $this->belongsToMany($modelName,$middle,$foreign_key,$local_key);
        };
        self::$model->macro($func,$closure);
    }

    /**
     * 获取字段值和注释
     *
     * @param string $table
     * @return array
     */
    public function getTableField(string $table): array
    {
        return $this->table->getTableField($table);
    }

    /**
     * @throws ModelEmptyException
     * @throws ModelException
     */
    public function getModuleField($param)
    {
        $module = self::getModule($param['module_id'],$param['seller_id']);
        return $module['moduleField'];
    }

    /**
     * 获取内容展示字段
     * @throws ModelException
     * @throws \app\exception\ModelEmptyException
     */
    public function getContentField($param): array
    {
        $module = self::getModule($param['module_id'],$param['seller_id']);
        $sort_field = [];
        $field = $this->getTableField($module['database_table']);
        // 自定义模型
        // 处理数组顺序,按照数据表字段排序，确定表单顺序
        $form_field = $module['moduleField'];
        foreach($form_field as $val){
            foreach($field as $k => $v){
                if(isset($v['column_name'])){
                    if($val['table_field'] == $v['column_name']){
                        $sort_field[$k] = $val;
                    }
                }else{
                    if($val['table_field'] == $v['COLUMN_NAME']){
                        $sort_field[$k] = $val;
                    }
                }
            }
        }

        ksort($sort_field);

        return $sort_field;
    }

    /**
     * @throws ModelEmptyException
     * @throws ModelException
     */
    public  static function getModule($module_id,$seller_id)
    {
        $moduleModel = new Module();
        return $moduleModel->getCustomArrayData(['id'=>$module_id,'seller_id'=> $seller_id],['moduleField','category'],'id,title,table')['data'];
    }

    /**
     * 获取分类
     * @throws \app\exception\ModelEmptyException
     * @throws ModelException
     */
    public static function getCate($param)
    {
        $category = new Category();
        return $category->getCategory($param,['module.moduleField'])['data']->toArray();
    }

    /**
     * 设置模型
     * @param string $table
     * @return mixed
     * @throws ModelEmptyException
     * @throws ModelException
     */
    public static function setModel(string $table)
    {
        $class = '\\app\\model\\' . ucfirst(camelize($table));
        $module = new Module();
        $tableFlag = $module->getCustomArrayData(['table'=>$table])['data'];
        if(!empty($tableFlag)){
            $class = '\\app\\model\\customModel\\' . ucfirst(camelize($table));
        }
        return self::$model = new $class();
    }

    /**
     * 组装附表数据
     * @param $param
     * @param $mainId
     * @return mixed
     */
    public function getSubData($param, $mainId, $isEdit = false)
    {
        $subData = $param['sub_content'];
        $subData['check_status'] = $param['check_status'] ?? 3;
        $subData['main_id'] = $mainId;
        $subData['seller_id'] = $param['admin']['seller_id'];
        $subData['admin_id'] = $param['admin']['uid'];
        if(empty($subData['author'])){
            $subData['author'] = $param['admin']['name'];
        }
        if($isEdit){
            $subData['id'] = $param['sub_id'];
        }
        if(empty($subData['tag'])){
            $subData['tag'] = '';
        }
        return $subData;
    }

    /**
     * 图片本地化
     * @param $content
     * @return array|string|string[]
     */
    public function imgExtraction($content,$sellerId,$website = '')
    {
        $filePath = date('Ymd');
        $imgPath = CMS_ROOT . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . 'storage' . DIRECTORY_SEPARATOR . 'image' . DIRECTORY_SEPARATOR .$filePath ;
        $content = $this->cleanContent($content);
        $content = htmlspecialchars_decode($content);
        $imgArr = getPatternMatchImages($content);
        $img_search = [];
        $img_replace = [];
        $attachmentData = [];
        if(!empty($imgArr)){
            foreach ($imgArr as $imgUrl){
                // 相同图片直接掠过
                if(in_array($imgUrl,$img_search)){
                    continue;
                }
                $img_search[] = $imgUrl;
                $ext=strrchr($imgUrl,".");
                ob_start();
                if(preg_match('/http/',$imgUrl)){
                    readfile($imgUrl);
                }else{
                    if(!preg_match('/^\/data/',$imgUrl)){
                        readfile($website . '/' .$imgUrl);
                    }
                }
                $img = ob_get_contents();
                ob_end_clean();
                $filename = md5(microtime(true).rand());
                $imgFile =  $imgPath . DIRECTORY_SEPARATOR . $filename .  $ext;
                if(!file_exists($imgPath)){
                    mkdir($imgPath);
                }
                $fp2=@fopen($imgFile, "a");
                fwrite($fp2,$img);
                fclose($fp2);
                $localPath = DIRECTORY_SEPARATOR . 'storage' . DIRECTORY_SEPARATOR . 'image' . DIRECTORY_SEPARATOR .$filePath .DIRECTORY_SEPARATOR . $filename .  $ext;
                // 保存到附件
                $size = filesize($imgFile);
                $tmpAttach = [
                    'seller_id' => $sellerId,
                    'name' => $filename,
                    'size' => round($size / 1024,2),
                    'url'  => DIRECTORY_SEPARATOR . 'storage' . DIRECTORY_SEPARATOR . 'image' . DIRECTORY_SEPARATOR .$filePath .DIRECTORY_SEPARATOR . $filename .  $ext,
                    'type' => 2,
                    'mime_type' => $ext,
                ];
                $attachmentData[] = $tmpAttach;
                $img_replace[] = $localPath;
            }
        }
        if(!empty($attachmentData)){
            $Attachment = new Attachment();
            $Attachment->addAllCustomData($attachmentData);
        }
        if(!empty($img_search) && !empty($img_replace)){
            $content = str_replace($img_search,$img_replace,$content);
        }
        return $content;
    }

    /**
     * 简介提取
     * @param $content
     * @param int $index
     * @return string
     */
    public function descExtraction($content, int $index = 0): string
    {
        if(empty($content)){
            return $content;
        }
        $content = $this->cleanContent($content);
        $content = htmlspecialchars_decode($content);
        $content = strip_tags($content);
        $content = str_replace(["\r","\n","\t","\r\n"],[''],$content);
        return trim(hcSubstr($content,100)) . '...';
    }

    /**
     * 文章导入
     * @param $param
     */
    public function articleUpload($param): array
    {
        if(empty($param['file'])){
            return dataReturn(0,lang('保存成功'));
        }
        $file = $param['file'];
        // 提取标题和简介
        $title = $file -> getOriginalName();
        $title = str_replace('.txt','',$title);
        $keywords = $title;
        $tmpName = $file->getPathname();
        $text = file_get_contents($tmpName);
        $tmpContent = strToUtf8($text);
        if(isset($param['pseudo']) &&  $param['pseudo'] == 1){
            $title = trim($this->pseudoOriginal($title,$param['admin']['seller_id']),PHP_EOL);
            $tmpContent = $this->pseudoOriginal($tmpContent,$param['admin']['seller_id']);
        }
        if($tmpContent == strip_tags($tmpContent)){
            if(strpos($tmpContent,"\r\n")){
                $tmpContentArr = explode("\r\n",$tmpContent);
            }else{
                $tmpContentArr = explode(PHP_EOL,$tmpContent);
            }
            $tmpContent ='';
            foreach($tmpContentArr as $tmpVal) {
                if(!empty($tmpVal)){
                    $tmpContent .= "<p>{$tmpVal}</p>" . PHP_EOL;
                }
            }
        }
        // 图片本地化
        $tmpContent = $this->imgExtraction($tmpContent,$param['admin']['seller_id']);
        $description = $this->descExtraction($tmpContent);
        $data = [
            'module_id' => $param['module_id'],
            'category_id' => $param['category_id'],
            'main_content' => [],
            'sub_content' => [
                'title' => $title,
                'description' => $description,
                'publish_time' => date('Y-m-d H:i:s'),
                'content' => $tmpContent,
                'seo_title' => $title,
                'seo_keyword' => $keywords,
                'seo_description' => $description,
            ],
            'admin' => $param['admin'],
        ];
        $res = $this->saveContent($data);
        if($res['code']){
            return $res;
        }
        $subContent = $res['data'];
        $InnerChart = new InnerChart();
        $keywordList = $InnerChart->getAllInnerChart(['seller_id'=>$param['admin']['seller_id'],'website_id'=>$param['website_id'],'status'=>1],'weight desc','id,weight,keyword,url,new_page_open')['data'];
        $subContent->content = $this->autoLinks($subContent->content,$keywordList,$subContent);
        $subContent->save();
        return $res;
    }

    /**
     * 去除 addslashes 添加的反斜杠
     * @param $content
     * @return string
     */
    public function cleanContent($content): string
    {
        return stripslashes($content);
    }

    /**
     * 内链插入
     * @param $content
     * @param $keywordList
     * @return array|string|string[]|null
     * @throws \think\db\exception\DbException
     */
    public function autoLinks($content, $keywordList,$subContent = null)
    {
        $keyNum = config('system.keyword_num');
        $urlNum = config('system.keyword_url');
        $links = [];
        $content = $this->cleanContent($content);
        $content = htmlspecialchars_decode($content);
        // 先移除已有的自动链接
        $content = preg_replace_callback('~<a data\-rel="autolink" .*?>(.*?)</a>~i', function ($match)use(&$old) {
            return $match[1];
        }, $content);
        if($subContent instanceof SubContent){
            $subContent -> innerChart() -> detach();
        }
        // 存储所有标签
        $content = preg_replace_callback('~(<a .*?>.*?</a>|<.*?>)~i', function ($match) use (&$links) {
            return '<' . array_push($links, $match[1]) . '>';
        }, $content);

        $cache = [];
        // 替换链接
        $i = 0;
        foreach ($keywordList as $item) {
            if($i >= $keyNum){
                break;
            }
            $count = 1;
            $specialStr = '~9c0h3a4s9f2-';
            $content = str_replace($item['keyword'],$specialStr,$content);
            $content = preg_replace_callback('/(' . $item['keyword'] . ')/i', function ($match) use ($item,&$i,&$count) {
                if(!empty($match) && $count == 1){
                    $i++;
                }
                $count++;
                $url = $item['url'];
                return '<a data-rel="autolink" href="' . $url . '"' . ($item['new_page_open'] == 2 ? ' target="_blank"' : '') . '>' . $match[0] . '</a>';
            }, $content, $urlNum,$count);
            $content = str_replace($specialStr,$item['keyword'],$content);
            $content = preg_replace_callback('~(<a .*?>.*?</a>)~i', function ($match) use (&$links) {
                return '<' . array_push($links, $match[1]) . '>';
            }, $content);
            if($i != 0){
                if($subContent instanceof SubContent){
                    $subContent -> innerChart() -> attach($item->id,['num'=>$i]);
                }else{
                    $tmpCache = [
                        'inner_chart_id' => $item -> id,
                        'total' => $i,
                    ];
                    $cache[] = $tmpCache;
                }
            }
        }
        $content = preg_replace_callback('/<(\d+)>/', function ($match) use (&$links) {
            return $links[$match[1] - 1];
        }, $content);
        if(!empty($cache)){
            Cache::set(md5(strip_tags($content)),$cache,300);
        }
        return $content;
    }

    public function getModuleContent($table,$sellerId): array
    {
        $table = str_replace(env('database.prefix'),'',$table);
        // 判断用户自定义模型
        $module = new Module();
        $sellerModule = $module -> getAllCustomArrayData(['seller_id'=>$sellerId])['data'];
        $sellerTable = array_column($sellerModule,'table');
        if(!empty($sellerTable) && in_array($table,$sellerTable)){
            $data = Db::name($table)->alias('cs')
                ->field('cs.*,sb.title as hc_main_title')
                ->leftJoin('sub_content sb','cs.sub_id = sb.id')
                ->where('sb.status',1)
                ->where('sb.is_del',1)
                ->order('cs.id desc')
                ->select()->toArray();
        }else{
            $ModuleFieldService = new ModuleFieldService();
            $field = $ModuleFieldService -> getModuleTableField(env('database.prefix') . $table)['data'];
            $field = array_column($field,'column_name');
            $query = Db::name($table)->where('seller_id',$sellerId);
            if(in_array('is_del',$field)){
                $query = $query -> where('is_del',1);
            }
            if ($table == 'diy_form') {
                $query = $query -> where('type',1);
            }

            $res = $query -> select()->toArray();
            $data = [];
            if(!empty($res)){
                foreach($res as $val) {
                    $tmp = $val;
                    $tmp['hc_main_title'] = empty($val['title']) ? $val['name'] : $val['title'];
                    $data[] = $tmp;
                }
            }
        }
        return dataReturn(0,'success',$data);
    }

    /**
     * 伪原创（百度翻译）
     * @throws ModelException
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function pseudoOriginal($q,$sellerId): string
    {
        $trans = new TranslateService();
        $data = $this -> dealTransData($q);

        $str = '';
        foreach ($data as $val){
            $result = $trans -> baiduTranslate($val,'zh','en',$sellerId)['data'];
            $res = $trans -> baiduTranslate($result,'en','zh',$sellerId)['data'];
            $str .= $res . PHP_EOL;
        }
        return $str;
    }

    /**
     * 翻译长度处理
     * @param $data
     * @param int $len
     * @return array
     */
    public function dealTransData($data, int $len = 6000,&$dataArr=[]): array
    {
        $len_s = strlen($data);
        if($len_s > $len){
            $data1 = substr($data,0,$len);
            $index_zh = strrpos($data1,'。');
            $index_en = strrpos($data1,'.');
            if($index_zh > $index_en){
                $index = $index_zh + 3;
            }else{
                $index = $index_en + 1;
            }
            $tmpData1 = substr($data1,0,$index) . PHP_EOL;
            $dataArr[] = $tmpData1;
            $tmpData = substr($data,$index,$len);
            $this->dealTransData($tmpData,$len,$dataArr);
        }else{
            $dataArr[] = $data;
        }
        return $dataArr;
    }


}
